package com.cloudbroker.bcs.common.aspect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import com.cloudbroker.bcs.common.entity.HSBCPSBackVO;
import com.cloudbroker.bcs.common.util.PrintUtil;

public class LogAspect {
    
    private static final String CLASS_NAME = LogAspect.class.getName();
    
    private static final Logger LOGGER = LoggerFactory.getLogger(CLASS_NAME);
    
    private String from = "";
    
    private String local = "";
    
    private String inMark;
    
    private String outMark;
    
    public LogAspect() {
        PrintUtil.printComponentLoaded(LOGGER, CLASS_NAME);
    }
    
    public Object log(ProceedingJoinPoint pjp) throws Throwable {
        LOGGER.info(getInMark() + Arrays.toString(pjp.getArgs()));
        long startTime = System.currentTimeMillis();
        Object result = null;
        try {
            result = pjp.proceed();
        } finally {
            try {
                // 在Spring的环境里，signature就是MethodSignature
                MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
                // 获取Method
                Method method = methodSignature.getMethod();
                long endTime = System.currentTimeMillis();
                String simpleName = pjp.getTarget().getClass().getSimpleName();
                if (simpleName.endsWith("T2")) {
                    Annotation annotation = method.getAnnotations()[0];
                    Method m = annotation.getClass().getDeclaredMethod("desc");
                    String desc = (String) m.invoke(annotation);
                    m = annotation.getClass().getDeclaredMethod("functionId");
                    String functionId = (String) m.invoke(annotation);
                    StringBuilder sb = new StringBuilder();
                    String resultMsg = null;
                    if (result instanceof HSBCPSBackVO) {
                        resultMsg = ((HSBCPSBackVO) result).getError_info();
                    }
                    sb.append(simpleName).append('.').append(method.getName()).append(':').append(result)
                            .append("\r\n").append(desc).append('-').append(functionId).append('-')
                            .append(resultMsg).append(" >>>>>>>> spend time ").append(endTime - startTime)
                            .append(" millis ");
                    LOGGER.debug(sb.toString());
                }
            } catch (Exception e) {
                LOGGER.error(e.getMessage());
            }
            MDC.clear();
        }
        return result;
    }
    
    public String getFrom() {
        return from;
    }
    
    public void setFrom(String from) {
        if (null == from) {
            from = "";
        }
        this.from = from;
        inMark = null;
    }
    
    public String getLocal() {
        return local;
    }
    
    public void setLocal(String local) {
        if (null == local) {
            local = "";
        }
        this.local = local;
        inMark = null;
    }
    
    public String getInMark() {
        if (null == inMark) {
            inMark = '[' + from + "->" + local + ']';
        }
        return inMark;
    }
    
    public void setInMark(String inMark) {
        this.inMark = inMark;
    }
    
    public String getOutMark() {
        if (null == outMark) {
            outMark = '[' + from + "<-" + local + ']';
        }
        return outMark;
    }
    
    public void setOutMark(String outMark) {
        this.outMark = outMark;
    }
    
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("LoggerAspect [from=").append(from).append(", local=").append(local).append(", inMark=")
                .append(inMark).append(", outMark=").append(outMark).append("]");
        return builder.toString();
    }
    
}
